/**
 * file created at 2010-6-17 下午09:55:42
 */
package org.lightframework.jamwiki.servlets;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jamwiki.Environment;
import org.jamwiki.servlets.ServletUtilEx.MimeTypes;

/**
 * servlet mapping to '/upload' to read the uploaded files and output to browser,includes images,txt,etc.
 *
 * @author fenghm(live.fenghm@gmail.com)
 */
public class UploadMappingServlet extends HttpServlet {
	
	public static final String HTTP_HEADER_LAST_MODIFIED = "Last-Modified";
	public static final String HTTP_HEADER_IF_MODIFIED_SINCE = "If-Modified-Since";	
	
    private static final long serialVersionUID = -3872958861498575630L;
    
	@Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		File file = getFile(request);
		
		if(null == file){
			response.setStatus(HttpServletResponse.SC_NOT_FOUND);
			return ;
		}else{
			long lastModified      = file.lastModified();
			long lastModifiedSince = request.getDateHeader(HTTP_HEADER_IF_MODIFIED_SINCE);
			
			//If-Modified-Since no millisecond
			if(lastModifiedSince > 0 && (lastModified - lastModifiedSince < 1000)){
				response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
				return ;
			}else{
				response.setContentType(MimeTypes.getByFileName(file.getName()));
				response.setContentLength((int)file.length());
				response.setDateHeader(HTTP_HEADER_LAST_MODIFIED, lastModified);
				
				output(file, response.getOutputStream());
				
				response.getOutputStream().flush();
				response.getOutputStream().close();
			}
		}
    }

	@Override
    protected long getLastModified(HttpServletRequest request) {
	    File file = getFile(request);
	    if(null != file){
	    	return file.lastModified();
	    }else{
	    	return super.getLastModified(request);
	    }
    }
	
	protected File getFile(HttpServletRequest request){
		String dir  = Environment.getValue(Environment.PROP_FILE_DIR_FULL_PATH);
		String path = getFilePath(request);
		
		if(null != path && !"".equals(path) && !"/".equals(path)){
			String fileName = dir.endsWith("/") ?  dir.substring(0,dir.length()-1) + path : dir + path;
			File file = new File(fileName);
			if(file.exists()){
				return file;
			}
		}		
		return null;
	}
	
	protected String getFilePath(HttpServletRequest request){
		String path = Environment.getValue(Environment.PROP_FILE_DIR_RELATIVE_PATH);
		String uri  = request.getRequestURI();
		int index   = uri.indexOf(path);
		if(index == 0){
			return uri.substring(path.length());
		}else{
			return null;
		}
	}
	
    protected void output(File file, OutputStream outputstream) throws IOException  {
        byte data[] = new byte[1024];
        BufferedInputStream buf = null;
		try {
			buf = new BufferedInputStream(new FileInputStream(file));
			int i;
			while ((i = buf.read(data, 0, 1024)) != -1) {
				outputstream.write(data, 0, i);
			}
		}finally{
			if(null != buf){
				try{
					buf.close();
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		}
    }
}
